/**
 *******************************************************************************
 * \brief   CAS EBX Project Work "Kaffeemaschine"
 *
 * \file    mill.c
 * \version 1.0
 * \date    30.06.2010
 * \author  Baehler Thomas, Liechti Beat, Sauter Marc
 * \author  Vuksic Valentina, Zbinden Rene
 *
 * \remark  Last Modifications:
 * \remark  V1.0, 30.06.2010   Initial release
 *******************************************************************************
 **/

/*
 *******************************************************************************
 * Definitions
 *******************************************************************************
 */
/** \brief The minimum amount of powder needed for a coffee */
#define AMOUNT_OF_POWDER 1


/*
 *******************************************************************************
 * Imports
 *******************************************************************************
 */
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
#include <unistd.h>

#include "coffee2.h"
#include "channel.h"
#include "pool.h"
#include "device.h"

/*
 *******************************************************************************
 * Local Variables
 *******************************************************************************
 */
static tChannel *c11, *c12; /*, *c24, *c25, *c26;*/
static tPool *p2, *p3;
static tDevice *d24, *d25, *d26;

/*
 *******************************************************************************
 * Local Function Declaration
 *******************************************************************************
 */
static void sigtermHandler(int signal);


/**
 *******************************************************************************
 * sigtermHandler
 *
 * \brief handle SIGTERM signal, close all pools and channels and exit
 *
 *******************************************************************************
 **/
static void sigtermHandler(int signal) {
	syslog(LOG_INFO, "SIGTERM reveiced, stopping ...");
	/* open channels and pools */
	closeChannel(c11);
	closeChannel(c12);
	//closeChannel(c24);
	//closeChannel(c25);
	//closeChannel(c26);
	closeDevice(d24);
	closeDevice(d25);
	closeDevice(d26);
	closePool(p2);
	closePool(p3);
	/* close syslog */
	closelog();
	/* close and remove the runfile */
	exit(EXIT_SUCCESS);
}


/**
 *******************************************************************************
 * mainMill
 *
 * \brief Activity: "Kaffee"
 *
 * \return pid
 *
 *******************************************************************************
 **/
pid_t mainMill(){
	pid_t pid;
	sigset_t sigmask;
	struct sigaction sigtermAction;
	enum e_errors error = NO_ERROR;
	int order = 0;
	int parameter = 0;
	int on = 1, off = 0;
	int coffeePowder = 0;

	pid = fork();
	if (pid == 0) {
		/* syslog */
		openlog("coffee-mill", LOG_PID, LOG_DAEMON);
		/* block all signals other than SIGTERM */
		sigemptyset(&sigmask);
		sigaddset(&sigmask, SIGTERM);
		sigtermAction.sa_handler = sigtermHandler;
		sigtermAction.sa_mask = sigmask;
		if (sigaction(SIGTERM, &sigtermAction, NULL) == -1){
			syslog(LOG_ERR, "unable to setup signal handling!");
		}
		/* open channels and pools */
		c11 = openChannelRead("C11", sizeof(int));  /* read from "Tasse" */
		c12 = openChannelWrite("C12", sizeof(int)); /* write to "Kaffee" */
		//c24 = openChannelRead("C24", sizeof(int));  /* read from "Pulvermenge */
		//c25 = openChannelWrite("C25", sizeof(int)); /* write to "Mahlwerk */
		//c26 = openChannelWrite("C26", sizeof(int)); /* read from "Dosierer */
		d24 = openDeviceRead("/dev/c2pwdrmtr");
		d25 = openDeviceWrite("/dev/c2coffgrn");
		d26 = openDeviceWrite("/dev/c2coffdfd");
		p2 = openPool("P2", sizeof(parameter));     /* "Parameter" */
		p3 = openPool("P3", sizeof(error));         /* "Error" */

		while (1) {
			if (readChannel(c11, &order) > 0) {
				syslog(LOG_INFO, "order from C11 received");
				/* read the parameter */
				readFromPool(p2, &parameter);
				/* start the coffee mill */
				syslog(LOG_INFO, "starting coffee mill");
				//writeChannel(c25, &on);
				writeDevice(d25, on);
				/*
				 * The amount of powder needed depends on the product,
				 * the parameter and the sensor function.
				 * The calculation will be done here in the future ...
				 * ... for now we take a static threshold.
				 */
				syslog(LOG_INFO, "checking amount of coffee powder ...");
				//readChannel(c24, &coffeePowder);
				readDevice(d24, &coffeePowder);
				while (coffeePowder < AMOUNT_OF_POWDER) {
					usleep(500);
					//readChannel(c24, &coffeePowder);
					readDevice(d24, &coffeePowder);
				}
				/* stop the coffee mill */
				syslog(LOG_INFO, "enough coffee powder - stopping mill");
				//writeChannel(c25, &off);
				writeDevice(d25, off);
				/* start the dosing feeder ... needs no stop */
				syslog(LOG_INFO, "starting dosing feeder");
				//writeChannel(c26, &on);
				writeDevice(d26, on);
				syslog(LOG_INFO, "sending order to C12");
				writeChannel(c12, &order);
			}
			usleep(500);
		}
	}
	return pid;
}




